package com.improvess.rna.som.knn;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import Jama.Matrix;

import com.improvess.rna.som.NeuronioPb;



public class Knn {
	
	private int neighbors ;
	private Pattern[] trainingSet;
	private List<Relationship> relations;
	private NeuronioPb[][] neuronios;
	private Map<String,Double> mapClasse_QtdElementos;
	
	
	public Knn(int k){
		neighbors = k;
		relations = new ArrayList<Relationship>();
		mapClasse_QtdElementos = new HashMap<String, Double>();
	}
	
	public Map<String,Double> processar(Matrix xi){
		
		for(Pattern padraoTreinamento : trainingSet){
			double distance = Euclidean.getDistance(padraoTreinamento.getAtributos(), xi);
			Relationship r = new Relationship(distance, padraoTreinamento);
			relations.add(r);
		}
		Collections.sort(relations);
		
		for(int k =0; k<neighbors;k++){
			Relationship r = relations.get(k);
			String label = r.getPattern().getLabel();
			if(!mapClasse_QtdElementos.containsKey(label)){
				mapClasse_QtdElementos.put(label, 0.0);
			}else{
				double valor = mapClasse_QtdElementos.get(label);
				valor++;
				mapClasse_QtdElementos.put(label, valor);
			}
		}
		Map<String,Double> probabilidadesPorClasse = calcularProbabilidades();
		clear();
		return probabilidadesPorClasse;
	}
	
	public Map<String,Double> calcularProbabilidades(){
		Map<String,Double> probabilidadesPorClasse = new HashMap<String, Double>();
		for(String classe : mapClasse_QtdElementos.keySet()){
			double valor = mapClasse_QtdElementos.get(classe);
			double probabilidade = valor/neighbors;
			probabilidadesPorClasse.put(classe, probabilidade);
		}
		return probabilidadesPorClasse;
	}

	
	public void setTrainingSet(Pattern[] trainingSet){
		this.trainingSet = trainingSet;
	}
	
	private void clear(){
		relations.clear();
	}

	public void setMapClasse_QtdElementos(Map<String,Double> mapClasse_QtdElementos) {
		this.mapClasse_QtdElementos = mapClasse_QtdElementos;
	}

	public Map<String,Double> getMapClasse_QtdElementos() {
		return mapClasse_QtdElementos;
	}

	public void setNeuronios(NeuronioPb[][] neuronios) {
		this.neuronios = neuronios;
	}

	public NeuronioPb[][] getNeuronios() {
		return neuronios;
	}
}